package com.uniledger.test;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import com.uniledger.test.model.Balance;
import com.uniledger.test.model.HttpResult;
import com.uniledger.test.model.PayResult;
import com.uniledger.test.model.SeeleAdmin;
import com.uniledger.test.network.Api;
import com.uniledger.test.utils.FileUtils;

import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.seele.RawTransaction;
import org.web3j.crypto.seele.Transaction;
import org.web3j.crypto.seele.TransactionEncoder;
import org.web3j.crypto.seele.TransactionUtils;
import org.web3j.utils.Numeric;
import org.web3j.utils.SeeleConvert;

import java.io.File;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;


public class MainActivity extends AppCompatActivity {

    TextView textView;
    private static int nonce = 8;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.hello);

        new WalletTask().execute();

    }

    class SeeleTask extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... strings) {
            String json = TransactionUtils.test();
            Log.d("Seele", json);
            return json;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

            textView.setText(s);
        }
    }

    class WalletTask extends AsyncTask<String, Integer, Transaction> {


        private void topUp(String addr) {
            if (TextUtils.isEmpty(addr)) {
                Map<String, String> params = new HashMap<>();
                params.put("remark", "TopUp");
                params.put("amount", SeeleConvert.toFan("100", SeeleConvert.Unit.ETHER).toString());
                params.put("card_id", "1");
                params.put("stellar_trx_sign", "sign");
                Api.getService().doCharge(params)
                        .subscribeOn(Schedulers.io())
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<HttpResult<PayResult>>() {
                            @Override
                            public void accept(HttpResult<PayResult> result) throws Exception {

                            }
                        }, new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
                                Log.d("Seele", throwable.getMessage());
                            }
                        });


            } else {
                Map<String, String> map = new HashMap<>();
                map.put("name", "seele999");
                map.put("country_code", "86");
                map.put("mobile", "" + System.currentTimeMillis());
                map.put("captcha", "123456");
                map.put("stellar_addr", addr);

                Api.getService().signUp(map)
                        .subscribeOn(Schedulers.io())
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<HttpResult<SeeleAdmin>>() {
                            @Override
                            public void accept(HttpResult<SeeleAdmin> result) throws Exception {

                            }
                        });
            }
        }

        private Transaction transfer(Credentials credentials) {

            final Function function = new Function(
                    "transfer",
                    Arrays.<Type>asList(new Address("0x6709632b58338a1d4c7c0a64aca3ac380d918b91"),
                            new Uint256(SeeleConvert.toFan("10", SeeleConvert.Unit.ETHER))),
                    Collections.<TypeReference<?>>emptyList());

            String to = "0xeb70b0e8828cb6a4b7f7367a8ffc68f90ca80012";

            BigInteger gasPriceInt = BigInteger.valueOf(10);
            BigInteger gasLimitInt = BigInteger.valueOf(100000);

            BigInteger valueInt = BigInteger.ZERO;
            BigInteger nonceInt = BigInteger.valueOf(nonce);

            String data = FunctionEncoder.encode(function);

            RawTransaction rawTx = RawTransaction.createTransaction(nonceInt, gasPriceInt, gasLimitInt, to, valueInt, data);

            Transaction tx = TransactionEncoder.signSeeleMessage(rawTx, credentials);

            return tx;


        }

        @Override
        protected Transaction doInBackground(String... strings) {

            File file = FileUtils.getSeeleFile();

//            try {
//                Credentials credentials = WalletUtils.loadSeeleCredentials(SampleKeys.PASSWORD, file.listFiles()[0]);

            Credentials credentials = Credentials.createSeele("da96870729e9e2b49881790de265211cc7162d28cde94fa96378d4fcc775390d");

            Log.d("Seele", credentials.getEcKeyPair().getKey());
            Log.d("Seele", credentials.getAddress());
            return transfer(credentials);
//            } catch (IOException e) {
//                e.printStackTrace();
//            } catch (CipherException e) {
//                e.printStackTrace();
//            }

//            try {
//                //生成助记词
//                Bip39Wallet wallet = WalletUtils.generateFixedShardBip39Wallet(SampleKeys.PASSWORD, FileUtils.getSeeleFile(), 1);
//                Credentials credentials = WalletUtils.loadSeeleBip39Credentials(SampleKeys.PASSWORD, wallet.getMnemonic());
//                return credentials.getAddress();
//            } catch (CipherException e) {
//                e.printStackTrace();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }


//            return null;

        }

        @Override
        protected void onPostExecute(Transaction tx) {
            super.onPostExecute(tx);

            Map<String, String> params = new HashMap<>();
            params.put("currency", "AED");
            params.put("amount", SeeleConvert.toFan("10", SeeleConvert.Unit.ETHER).toString());
            params.put("payee_id", "6");
            params.put("remark", "");
            params.put("name", "AAA");
            params.put("txhash", tx.Hash);
            params.put("signature", tx.Signature.Sig);
            params.put("gasprice", "10");
            params.put("payload", Numeric.prependHexPrefix(tx.Data.getData()));
            params.put("nonce", "" + nonce);

//            Api.getService().doTransfer(params).subscribeOn(Schedulers.io())
//                    .subscribeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Consumer<HttpResult<PayResult>>() {
//                        @Override
//                        public void accept(HttpResult<PayResult> result) throws Exception {
//
//                        }
//                    }, new Consumer<Throwable>() {
//                        @Override
//                        public void accept(Throwable throwable) throws Exception {
//                            Log.d("Seele", throwable.getMessage());
//                        }
//                    });

            Log.d("Seele", Numeric.decodeQuantity("0x000000000000000000000000000000000000000000000004563918244f400000").toString());

            Api.getService().getBalance()
                    .subscribeOn(Schedulers.io())
                    .subscribeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<HttpResult<List<Balance>>>() {
                        @Override
                        public void accept(HttpResult<List<Balance>> result) throws Exception {
                            Log.d("Seele", result.toString());
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.d("Seele", throwable.getMessage());
                        }
                    });
        }
    }


}
